/**
 * crawler
 *
 * outlook@China software studio
 * Copyright (c) 2008-2011. All Rights Reserved.
 * http://www.outlook.com
 */

package org.outlook.common.data;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * function:
 * @author watson  email: watson.wu@hotmail.com
 * @date 2011-4-27
 */
public class KeyValueArrayList extends ArrayList<KeyValue> {

	private static final long serialVersionUID = 1L;
	
	private Map<String, Object> map = new HashMap<String, Object>(1);

	public KeyValueArrayList() {
		super();
	}

	public KeyValueArrayList(int initialCapacity) {
		super(initialCapacity);
	}

	@Override
	public boolean add(KeyValue e) {
		if(e == null) return false;
		boolean flag = super.add(e);
		synchronized (map) {
			map.put(e.getKey(), e.getValue());
		}
        return flag;
	}
	
	@Override
	public boolean addAll(Collection<? extends KeyValue> c) {
		if(c == null || contains(null)) return false;
		boolean flag =  super.addAll(c);
		synchronized (map) {
			for(KeyValue e : c)
			map.put(e.getKey(), e.getValue());
		}
		return flag;
	}

	@Override
	public boolean addAll(int index, Collection<? extends KeyValue> c) {
		if(c == null || contains(null)) return false;
		boolean flag = super.addAll(index, c);
		synchronized (map) {
			for(KeyValue e : c)
				map.put(e.getKey(), e.getValue());
		}
		return flag;
	}

	@Override
	public KeyValue remove(int index) {
		KeyValue o = super.remove(index);
		synchronized (map) {
			map.remove(o.getKey());
		}
		return o;
	}

	@Override
	public boolean remove(Object o) {
		boolean flag = super.remove(o);
		if(null != o)
			synchronized (map) {
				map.remove(((KeyValue)o).getKey());
			}
		return flag;
	}

	@Override
	protected void removeRange(int fromIndex, int toIndex) {
		List<KeyValue> subList = subList(fromIndex, toIndex);
		//super.removeRange(fromIndex, toIndex);
		removeAll(subList);
	}

	@Override
	public KeyValue set(int index, KeyValue element) {
		KeyValue keyValue = super.get(index);
		KeyValue value = super.set(index, element);
		synchronized (map) {
			map.remove(keyValue.getKey());
			map.put(value.getKey(), value.getValue());
		}
		return value;
	}

	@Override
	public boolean removeAll(Collection<?> c) {
		boolean flag = super.removeAll(c);
		synchronized (map) {
			for(Object e : c)
			map.remove(((KeyValue)e).getKey());
		}
		return flag;
	}

	@Override
	public boolean retainAll(Collection<?> c) {
		boolean flag = super.retainAll(c);
		synchronized (map) {
			map.clear();
			
			for(Iterator<KeyValue> iterator = iterator(); iterator.hasNext();) {
				final KeyValue next = iterator.next();
				map.put(next.getKey(), next.getValue());
			}
		}
		return flag;
	}

	public Object get(String key) {
		return map.get(key);
	}

}
